<template>
  <el-card>
    <el-form
      label-width="120px"
      size="small"
      :model="formData"
      :rules="rules"
      ref="ruleForm"
    >
      <el-form-item label="SPU名称" prop="spuName">
        <el-input placeholder="SPU名称" v-model="formData.spuName"></el-input>
      </el-form-item>
      <el-form-item label="品牌" prop="tmId">
        <el-select placeholder="请选择" v-model="formData.tmId">
          <el-option
            :value="tm.id"
            :label="tm.tmName"
            v-for="tm in tmList"
            :key="tm.id"
          >
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述" prop="description">
        <el-input
          type="textarea"
          rows="3"
          placeholder="SPU描述"
          v-model="formData.description"
        ></el-input>
      </el-form-item>
      <el-form-item label="SPU图片" prop="spuImageList">
        <el-upload
          :action="`${baseUrl}/admin/product/fileUpload`"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :on-success="handleAvatarSuccess"
          :before-upload="beforeAvatarUpload"
          :file-list="fileList"
        >
          <i class="el-icon-plus"></i>
        </el-upload>

        <el-dialog :visible.sync="dialogVisible">
          <img width="100%" :src="dialogImageUrl" alt="" />
        </el-dialog>
      </el-form-item>
      <el-form-item label="销售属性" prop="spuSaleAttrList">
        <el-select
          v-model="baseSaleAttrId"
          :placeholder="`还有${comBaseSaleAttrList.length}项未选择`"
        >
          <el-option
            v-for="s in comBaseSaleAttrList"
            :key="s.id"
            :value="s.id"
            :label="s.name"
          ></el-option>
        </el-select>
        <el-button
          type="primary"
          size="small"
          class="ml-20"
          @click="addSaleAttr"
          :disabled="!baseSaleAttrId"
        >
          添加销售属性
        </el-button>
        <el-table
          border
          :data="formData.spuSaleAttrList"
          class="attr-value-table"
        >
          <el-table-column
            type="index"
            label="序号"
            width="100px"
            align="center"
          ></el-table-column>
          <el-table-column label="属性名" prop="saleAttrName"></el-table-column>
          <el-table-column label="属性值名称">
            <template #default="{ row }">
              <el-tag
                v-for="(value, index) in row.spuSaleAttrValueList"
                :key="value.saleAttrValueName"
                size="mini"
                closable
                class="attr-value-tag"
                @close="closeTagHandle(row, index)"
              >
                {{ value.saleAttrValueName }}
              </el-tag>
              <el-button
                icon="el-icon-plus"
                size="mini"
                @click="addSaleAttrValue(row)"
                v-if="!row.showInput"
              ></el-button>
              <el-input
                class="attr-value-input"
                size="mini"
                v-model="inputValue"
                @blur="inputBlurHandle(row)"
                ref="inputRef"
                v-else
                @keydown.native.enter="$refs.inputRef.blur()"
              />
            </template>
          </el-table-column>
          <el-table-column label="操作" width="120px" align="center">
            <template #default="{ $index }">
              <el-button
                icon="el-icon-delete"
                size="mini"
                type="danger"
                @click="delBtnHandle($index)"
              ></el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')">
          保存
        </el-button>
        <el-button @click="$emit('changShowNum', 1)">取消</el-button>
      </el-form-item>
    </el-form>
  </el-card>
</template>

<script>
import {
  getTmListApi,
  getBaseSaleAttrListApi,
  addSpuInfoApi,
  getSpuImageListApi,
  getSpuSaleAttrListApi,
  updateSpuInfoApi
} from '@/api/product/spuApi'
import { mapState } from 'vuex'
export default {
  name: 'AddOrUpdateSpu',
  props: {
    toAddSpuData: {
      type: Object,
      required: true,
      default: () => ({})
    }
  },
  data() {
    // 验证规则
    const attrListValid = (rule, value, callback) => {
      if (!value.length) {
        callback(new Error('请添加销售属性'))
      } else if (value.some((item) => !item.spuSaleAttrValueList.length)) {
        callback(new Error('每个销售属性至少有一个属性值'))
      } else {
        callback()
      }
    }
    return {
      dialogImageUrl: '',
      baseUrl: process.env.VUE_APP_BASE_API,
      fileList: [],

      tmList: [],
      baseSaleAttrList: [],
      baseSaleAttrId: undefined,
      dialogVisible: false,
      inputValue: '',

      formData: {
        ...this.toAddSpuData,
        spuSaleAttrList: [],
        spuImageList: [] // imgName, imgUrl
      },
      // 表单校验
      rules: {
        spuName: [
          { required: true, message: '请输入spu名称', trigger: 'blur' }
        ],
        tmId: [{ required: true, message: '请选择品牌', trigger: 'change' }],
        description: [
          { required: true, message: '请输入spu描述', trigger: 'blur' }
        ],
        spuImageList: [{ required: true, message: '请上传图片' }],
        spuSaleAttrList: [{ required: true, validator: attrListValid }]
      }
    }
  },
  computed: {
    comBaseSaleAttrList() {
      return this.baseSaleAttrList.filter((attr) => {
        return !this.formData.spuSaleAttrList.some(
          (saleAttr) => saleAttr.baseSaleAttrId === attr.id
        )
      })
    },
    ...mapState('category', ['category'])
  },
  mounted() {
    Promise.all([
      this.getTmList(),
      this.getBaseSaleAttrList(),
      this.getSpuImgList(),
      this.getSpuSaleAttrList()
    ])
  },
  methods: {
    // 表单提交
    submitForm(formName) {
      this.$refs[formName].validate(async (valid) => {
        if (valid) {
          if (this.formData.id) {
            await updateSpuInfoApi({
              ...this.formData,
              category3Id: this.category.category3Id
            })
            this.$message.success('修改成功')
          } else {
            await addSpuInfoApi({
              ...this.formData,
              category3Id: this.category.category3Id
            })
            this.$message.success('添加成功')
          }
          console.log(this.formData)
          this.$emit('changShowNum', 1)
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    // 删除图片
    handleRemove(file, fileList) {
      const i = this.formData.spuImageList.findIndex(
        (img) => img.imgName === file.name
      )
      this.formData.spuImageList.splice(i, 1)
      this.fileList.splice(i, 1)
    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },
    // 图片上传成功
    handleAvatarSuccess(res, file, fileList) {
      this.$refs.ruleForm.clearValidate(['spuImageList'])
      this.fileList = fileList
      const imgObj = {
        imgName: file.name,
        imgUrl: res.data
      }
      this.formData.spuImageList.push(imgObj)
    },
    // 图片上传之前的验证
    beforeAvatarUpload(file) {
      const isJPG = file.type === 'image/jpeg'
      const isPNG = file.type === 'image/png'
      const isWEBP = file.type === 'image/webp'
      const isLt2M = file.size / 1024 / 1024 < 1

      if (!isJPG && !isPNG && !isWEBP) {
        this.$message.error('上传头像图片只能是 JPG/PNG/WEBP 格式!')
        return false
      }
      if (!isLt2M) {
        this.$message.error('上传头像图片大小不能超过 1MB!')
        return false
      }
      return true
    },
    // 封装获取品牌列表的函数
    async getTmList() {
      const res = await getTmListApi()
      this.tmList = res.data
    },
    // 封装获取基础销售属性的函数
    async getBaseSaleAttrList() {
      const res = await getBaseSaleAttrListApi()
      this.baseSaleAttrList = res.data
    },
    // 添加销售属性按钮
    addSaleAttr() {
      const saleAttr = {
        baseSaleAttrId: this.baseSaleAttrId,
        saleAttrName: this.baseSaleAttrList.find(
          (item) => item.id === this.baseSaleAttrId
        ).name,
        spuSaleAttrValueList: [],
        showInput: false
      }
      this.baseSaleAttrId = undefined

      this.formData.spuSaleAttrList.push(saleAttr)
    },
    // 添加按钮
    async addSaleAttrValue(data) {
      data.showInput = true
      this.$nextTick((_) => {
        this.$refs.inputRef.focus()
      })
    },
    // 输入框失去焦点
    inputBlurHandle(data) {
      data.showInput = false
      if (
        !this.inputValue ||
        data.spuSaleAttrValueList.some(
          (item) => item.saleAttrValueName === this.inputValue
        )
      ) {
        return
      }
      data.spuSaleAttrValueList.push({
        baseSaleAttrId: data.baseSaleAttrId,
        saleAttrValueName: this.inputValue
      })
      this.inputValue = ''
    },
    // 删除标签
    closeTagHandle(data, index) {
      data.spuSaleAttrValueList.splice(index, 1)
    },
    // 删除按钮
    delBtnHandle(index) {
      this.formData.spuSaleAttrList.splice(index, 1)
    },
    // 请求图片的方法
    async getSpuImgList() {
      if (!this.formData.id) return
      const res = await getSpuImageListApi(this.formData.id)
      res.data.forEach((item) => {
        this.formData.spuImageList.push(item)
        this.fileList.push({ name: item.imgName, url: item.imgUrl })
      })
    },
    // 请求销售属性的方法
    async getSpuSaleAttrList() {
      if (!this.formData.id) return
      const res = await getSpuSaleAttrListApi(this.formData.id)
      this.formData.spuSaleAttrList = res.data.map((item) => {
        item.showInput = false
        return item
      })
    }
  }
}
</script>

<style scoped>
.ml-20 {
  margin-left: 20px;
}
.attr-value-input {
  width: 150px;
}
.attr-value-tag {
  margin: 0 5px;
}
.attr-value-table {
  margin: 20px 0;
}
</style>
